home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_5_6.arc / SHELLASM.ASM < prev    next >
Assembly Source File  |  1987-09-15  |  46KB  |  915 lines

  1. ;Copyright 1987, John J. Newlin
  2.  
  3. PUBLIC setxy,upcase,cga_retrace,fillstr,screenwrite,init_screen,savebox
  4. PUBLIC restbox,shiftl,shiftr,hi,lo,move,chdir,findfirst,findnext,cls
  5. PUBLIC strng,video_mode,set_mem,getdir,msdos,set_dta,scroll,keycode
  6. PUBLIC exec,hide_cursor,rest_cursor,save_cursor,longstr,addlong
  7.  
  8. toolcode    segment word PUBLIC 'code'
  9.             assume cs:toolcode
  10.  
  11. ;;;;;;;;;;;;;;
  12. ;changes lower case char to upper case
  13. ;function upcase(ch : char) : char
  14. upcase       proc near
  15.              push bp
  16.              mov bp,sp                       ;save BP
  17.              mov ax,[bp+4]                   ;get the char
  18.              cmp al,97                       ;is it 'a' or above?
  19.              jb u_exit                       ;no, do nothing
  20.              cmp al,122                      ;is it 'z' or below?
  21.              ja u_exit                       ;no, do nothing
  22.              sub al,32                       ;change to upper case
  23. u_exit:      mov [bp+6],ax                   ;return as function result
  24.              pop bp
  25.              ret 2
  26. upcase       endp
  27.  
  28. ;;;;;;;;;;;;;;;
  29. ;uses undocumented interrupt 2E to execute a program
  30. ;procedure exec(var name : string);
  31. exec              proc near
  32.                   push bp                     ;save bp
  33.                   mov bp,sp                   ;bp points to the stack
  34.                   push ax                     ;save
  35.                   push bx                     ; all
  36.                   push cx                     ;  other
  37.                   push dx                     ;   regs
  38.                   push di
  39.                   push si
  40.                   jmp past                    ;jump over storage area
  41. mls_ds  dw 0                                  ;stores our DS reg
  42. mls_es  dw 0                                  ;stores our ES reg
  43. mls_ss  dw 0                                  ;stores our SS reg
  44. mls_sp  dw 0                                  ;stores our SP reg
  45. mls_bp  dw 0                                  ;stores our BP reg
  46. past:
  47.                   mov cs:mls_ss,ss            ;save SS reg
  48.                   mov cs:mls_sp,sp            ;save SP reg
  49.                   mov cs:mls_es,es            ;save ES reg
  50.                   mov cs:mls_ds,ds            ;save DS reg
  51.                   mov cs:mls_bp,bp            ;save BP reg
  52.                   push ds
  53.                   pop es                      ;set ES = DS
  54.                   mov si,[bp+4]               ;si points to command string
  55.                   int 2Eh                     ;call DOS to execute
  56.                   mov ax,cs:mls_ss            ;retrieve SS reg
  57.                   mov ss,ax                   ;reset it
  58.                   mov sp,cs:mls_sp            ;retrieve SP reg
  59.                   mov ax,cs:mls_ds            ;retrieve DS reg
  60.                   mov ds,ax                   ;reset it
  61.                   mov ax,cs:mls_es            ;retrieve ES reg
  62.                   mov es,ax                   ;reset it
  63.                   mov bp,cs:mls_bp            ;retrieve BP reg
  64.                   pop si                      ;restore
  65.                   pop di                      ; all
  66.                   pop dx                      ;  other
  67.                   pop cx                      ;   regs
  68.                   pop bx
  69.                   pop ax
  70.                   pop bp
  71.                   ret 2
  72. exec              endp
  73.  
  74. ;;;;;;;;;;;;
  75. ;returns keyboard status byte, ascii code, and scan code
  76. ;function keycode(var status,ascii,scan : integer) : boolean;
  77. keycode           proc near
  78.                   push bp
  79.                   mov bp,sp                   ;BP points to stack
  80.                   push bx                     ;Marshal says save BX
  81.                   push si                     ;and also SI
  82.                   mov ah,1                    ;Int 16h to check buffer
  83.                   int 16h                     ;call BIOS
  84.                   mov word ptr [bp+10],0      ;function returns a false
  85.                   jz _no_key                  ;no key avail, so depart
  86.                   mov ah,0                    ;key is avail, so get it
  87.                   int 16h                     ;call BIOS
  88.                   push ax                     ;save result
  89.                   mov ah,2                    ;to get status byte
  90.                   int 16h                     ;call BIOS
  91.                   mov bx,[bp+8]               ;get address of status
  92.                   mov ah,0                    ;zero the MSB
  93.                   mov [bx],ax                 ;set status
  94.                   pop ax                      ;restore AX
  95.                   mov bx,[bp+6]               ;get address of ascii
  96.                   mov si,[bp+4]               ;get address of scan
  97.                   xor dx,dx                   ;zero DX
  98.                   mov dl,ah                   ;put scan value in DX
  99.                   mov [si],dx                 ;move it into scan
  100.                   mov dl,al                   ;move ascii code into DL
  101.                   mov [bx],dx                 ;and into ascii
  102.                   mov word ptr[bp+10],1       ;function returns true
  103. _no_key:          pop si
  104.                   pop bx
  105.                   pop bp
  106.                   ret 6
  107. keycode           endp
  108.  
  109. ;;;;;;;;;;;;;;;
  110. ;scrolls the specified area of the screen up/down number of lines
  111. ;normalize to screen dimensions of (1,1) to (25,80)
  112. ;procedure scroll(ulx,uly,lrx,lry,lines,attr,dir : integer); external;
  113. scroll        proc near
  114.               push bp
  115.               mov bp,sp                       ;BP points to stack
  116.               push bx                         ;must preserve BX
  117.               mov bh,byte ptr 6[bp]           ;get desired attribute
  118.               mov ch,byte ptr 14[bp]          ;upper left y coord
  119.               dec ch                          ;normalize
  120.               mov cl,byte ptr 16[bp]          ;upper left x coord
  121.               dec cl                          ;normalize
  122.               mov dh,byte ptr 10[bp]          ;lower right y coord
  123.               dec dh                          ;normalize
  124.               mov dl,byte ptr 12[bp]          ;lower right x coord
  125.               dec dl                          ;normalize
  126.               mov al,byte ptr 08[bp]          ;no. of lines to scroll
  127.               cmp byte ptr 4[bp],0            ;scroll up?
  128.               je scroll_up                    ;yes
  129.               mov ah,7                        ;no, scroll down
  130.               jmp short scroll_it             ;do it
  131. scroll_up:    mov ah,6                        ;scroll up
  132. scroll_it:    int 10h                         ;call BIOS
  133.               pop bx
  134.               pop bp
  135.               ret 14
  136. scroll        endp
  137.  
  138. ;;;;;;;;;;;;;
  139. ;set the Disk Transfer Area to desired structure
  140. ;procedure set_dta(var buffer : buff_type);
  141. set_dta           proc near
  142.                   push bp
  143.                   mov bp,sp                   ;BP points to stack
  144.                   mov dx,[bp+4]               ;get address of buffer
  145.                   mov ah,1Ah                  ;function to set DTA
  146.                   int 21h                     ;DOS will do it
  147.                   pop bp
  148.                   ret 2
  149. set_dta           endp
  150.  
  151. ;;;;;;;;;;;;;;
  152. ;call DOS interrupt 21h with registers set as desired
  153. ;procedure msdos(var regs : regtype)
  154. msdos             proc near
  155.                   push bp
  156.                   mov bp,sp                   ;BP points to stack
  157.                   push ax                     ;save
  158.                   push bx                     ; all
  159.                   push cx                     ; regs
  160.                   push dx                     ;
  161.                   push di                     ;
  162.                   push si                     ;
  163.                   push ds                     ;
  164.                   push es                     ;
  165.                   jmp short pst               ;leap over code seg data
  166. saveit dw 0
  167. pst:
  168.                   mov bx,[bp+4]               ;BX points to regs structure
  169.                   mov ax,[bx+0]               ;set AX
  170.                   mov cx,[bx+4]               ;set CX
  171.                   mov dx,[bx+6]               ;set DX
  172.                   mov di,[bx+8]               ;set DI
  173.                   mov si,[bx+10]              ;set SI
  174.                   mov cs:saveit,ds            ;save our DS reg
  175.                   push [bx+14]                ;push ES value in structure
  176.                   pop es                      ;pop it into ES
  177.                   push [bx+2]                 ;push BX value in structure
  178.                   push [bx+12]                ;push DS value in structure
  179.                   pop ds                      ;set DS
  180.                   pop bx                      ;set BX
  181.                   push bp                     ;save our BP during call
  182.                   int 21h                     ;call DOS
  183.                   pop bp                      ;restore our BP
  184.                   push ds                     ;save returned DS
  185.                   push bx                     ;save returned BX
  186.                   mov bx,cs:saveit            ;get our DS reg
  187.                   mov ds,bx                   ;set our DS
  188.                   mov bx,[bp+4]               ;get pointer to structure
  189.                   pop [bx+2]                  ;set structure BX
  190.                   pop [bx+12]                 ;set structure DS
  191.                   mov [bx+0],ax               ;set structure AX
  192.                   mov [bx+4],cx               ;set structure CX
  193.                   mov [bx+6],dx               ;set structure DX
  194.                   mov [bx+8],di               ;set structure DI
  195.                   mov [bx+10],si              ;set structure SI
  196.                   push es                     ;push returned ES
  197.                   pop [bx+14]                 ;pop it into structure ES
  198.                   pushf                       ;push returned flags
  199.                   pop [bx+16]                 ;pop into structure flags
  200.                   pop es                      ;restore
  201.                   pop ds                      ; all
  202.                   pop si                      ;  regs
  203.                   pop di                      ;
  204.                   pop dx                      ;
  205.                   pop cx                      ;
  206.                   pop bx                      ;
  207.                   pop ax                      ;
  208.                   pop bp                      ;
  209.                   ret 2
  210. msdos             endp
  211.  
  212. ;;;;;;;;;;;;;
  213. ;returns active drive and directory in string
  214. ;drive code 0 = A, 1 = B, etc.
  215. ;procedure getdir(var dirname : string);
  216. getdir            proc near
  217.                   push bp
  218.                   mov bp,sp                   ;BP points to stack
  219.                   push si                     ;must preserve SI
  220.                   mov si,[bp+4]               ;SI points to dirname
  221.                   mov ah,19h                  ;set up to get drive desig
  222.                   int 21h                     ;call DOS
  223.                   add al,65                   ;make it a char
  224.                   mov byte ptr[si],al         ;put in string
  225.                   inc si                      ;point to next char
  226.                   mov al,58                   ;58 = ':'
  227.                   mov byte ptr[si],al         ;put in string
  228.                   inc si                      ;point to next char
  229.                   mov byte ptr[si],'\'        ;put in backslash
  230.                   inc si                      ;point to next char
  231.                   mov ah,47h                  ;set up to get default dir
  232.                   int 21h                     ;call DOS
  233.                   pop si
  234.                   pop bp
  235.                   ret 2
  236. getdir            endp
  237.  
  238. ;;;;;;;;;;;;;;
  239. ;set program memory to only what is required by code, data, and stack
  240. ;function set_mem : integer;
  241. set_mem           proc near
  242.                   push bp                     ;save BP
  243.                   mov bp,sp                   ;BP points to stack
  244.                   push es                     ;save ES
  245.                   push bx                     ;save BX
  246.                   mov ax,ds                   ;AX = DS
  247.                   mov bx,cs                   ;BX = CS
  248.                   sub ax,bx                   ;ds-cs = data seg paragraphs
  249.                   inc ax                      ;round up one
  250.                   mov bx,ax                   ;store in BX
  251.                   mov ax,bp                   ;AX = stack pointer
  252.                   mov cl,4                    ;for shifting
  253.                   shr ax,cl                   ;convert to paragraphs
  254.                   add ax,bx                   ;add BX
  255.                   add ax,32                   ;bump by 32 paragraph overhead
  256.                   mov bx,ax                   ;store in BX
  257.                   mov cx,ax                   ;save in CX
  258.                   mov ax,cs                   ;AX = code segment
  259.                   sub ax,16                   ;AX set to mem control block seg
  260.                   mov es,ax                   ;ES = mem control block seg
  261.                   mov ah,4Ah                  ;DOS mod alloc mem function
  262.                   int 21h                     ;DOS will do it
  263.                   jnc no_mem_err              ;error will set carry flag
  264.                   mov cx,-1                   ;if error return -1
  265. no_mem_err:       mov [bp+4],cx               ;function result
  266.                   pop bx                      ;restore BX
  267.                   pop es                      ;restore ES
  268.                   pop bp                      ;restore BP
  269.                   ret
  270. set_mem           endp
  271.  
  272. ;;;;;;;;;;;;;;;
  273. ;converts an integer into a Pascal string
  274. ;procedure strng(num : integer; var numstr : string)
  275. strng             proc near
  276.                   push bp
  277.                   mov bp,sp                   ;BP points to stack
  278.                   push bx                     ;preserve BX
  279.                   push di                     ;preserve DI
  280.                   push es                     ;preserve ES
  281.                   push ds                     ;preserve DS
  282.                   mov ax,ds                   ;get DS
  283.                   mov es,ax                   ;make ES = DS
  284.                   mov di,[bp+4]               ;DI points to string
  285.                   mov dx,[bp+6]               ;AX = integer to convert
  286.                   xor bx,bx                   ;zero BX
  287. new_char:         mov ax,dx
  288.                   xor dx,dx                   ;zero DX
  289.                   mov cx,10                   ;for decimal conversion
  290.                   div cx                      ;AX gets result
  291.                   xchg ax,dx                  ;swap AX and DX
  292.                   add al,30h                  ;convert to ascii
  293.                   push ax                     ;save AX
  294.                   inc bx                      ;bump count
  295.                   cmp dx,0                    ;are we done?
  296.                   jnz new_char                ;no, get another digit
  297. str_loop:
  298.                   pop ax                      ;restore AX
  299.                   stosb                       ;put in string
  300.                   dec bx                      ;dec count
  301.                   cmp bx,0                    ;are we done?
  302.                   jne str_loop                ;no, do again
  303.                   mov al,0                    ;AL = 0
  304.                   stosb                       ;end of string byte
  305.                   pop ds                      ;restore
  306.                   pop es                      ; regs
  307.                   pop di                      ;
  308.                   pop bx                      ;
  309.                   pop bp                      ;
  310.                   ret 4
  311. strng             endp
  312.  
  313. ;;;;;;;;;;;
  314. ;clears the entire screen using the specified attribute
  315. ;procedure cls(attr : integer);
  316. cls               proc near
  317.                   push bp
  318.                   mov bp,sp                   ;BP points to stack
  319.                   push bx                     ;preserve BX
  320.                   mov ah,7                    ;code to scroll
  321.                   mov al,0                    ;AL = 0 so all will be blanked
  322.                   mov bh,byte ptr[bp+4]       ;attribute for scroll
  323.                   mov cx,0                    ;CL = 0, CH = 0
  324.                   mov dx,184Fh                ;DL = 79, DH = 24
  325.                   int 10h                     ;call BIOS
  326.                   pop bx                      ;restore BX
  327.                   pop bp
  328.                   ret 2
  329. cls               endp
  330.  
  331. ;;;;;;;;;;;;;;;;;
  332. ;returns current video mode
  333. ;function vide_mode : integer
  334. video_mode        proc near
  335.                   push bp
  336.                   mov bp,sp                   ;BP points to stack
  337.                   mov ah,0Fh                  ;set up to get mode
  338.                   int 10h                     ;call BIOS
  339.                   mov ah,0                    ;clear upper half
  340.                   mov 4[bp],ax                ;return function result
  341.                   pop bp
  342.                   ret
  343. video_mode        endp
  344.  
  345.  
  346. ;;;;;;;;;;;;;;;;;;
  347. ;if file is found, returns a 0 - returns non-zero otherwise
  348. ;function findfirst(var pathname : string; attr : integer) : integer
  349. findfirst         proc near
  350.                   push bp
  351.                   mov bp,sp                   ;BP points to stack
  352.                   mov dx,[bp+6]               ;DX points to ASCIIZ string
  353.                   mov cx,[bp+4]               ;CX = file attribute
  354.                   mov ah,4Eh                  ;set up to find first
  355.                   int 21h                     ;call DOS
  356.                   jc ff_err                   ;carry flag set if not found
  357.                   mov ax,0                    ;was found, so AX = 0
  358. ff_err:           mov [bp+8],ax               ;return function result
  359.                   pop bp
  360.                   ret 4
  361. findfirst         endp
  362.  
  363. ;;;;;;;;;;;;;;;;;;
  364. ;returns 0 if next find is successful, non-zero if not
  365. ;function findnext : integer
  366. findnext          proc near
  367.                   push bp
  368.                   mov bp,sp                   ;BP points to stack
  369.                   mov ah,4Fh                  ;set up for find next
  370.                   int 21h                     ;call DOS
  371.                   jc fn_err                   ;carry flag set if not found
  372.                   mov ax,0                    ;was found, so AX = 0
  373. fn_err:           mov [bp+4],ax               ;return function result
  374.                   pop bp
  375.                   ret
  376. findnext          endp
  377.  
  378. ;;;;;;;;;;;;;;;;;;;;;;;
  379. ;changes to specified drive/directory
  380. ;returns 0 if successful, non-zero if not
  381. ;function chdir(var dirname : string) : integer;
  382. chdir             proc near
  383.                   push bp
  384.                   mov bp,sp                   ;BP points to stack
  385.                   push si                     ;must preserve SI
  386.                   mov si,[bp+4]               ;SI points to dirname
  387.                   cmp byte ptr [si+1],':'     ;is drive spec present
  388.                   jne no_drive                ;if not, skip drive stuff
  389.                   mov dl,[si]                 ;yes, get drive letter
  390.                   cmp dl,65                   ;is it below 'A'
  391.                   jb no_drive                 ;yes, skip
  392.                   cmp dl,90                   ;is it above 'Z'
  393.                   ja lo_case_desig            ;yes, check lower case
  394.                   sub dl,65                   ;convert letter to byte
  395.                   jmp drv_ok                  ;continue
  396. lo_case_desig:    cmp dl,97                   ;is it below 'a'
  397.                   jb no_drive                 ;yes, skip
  398.                   cmp dl,122                  ;is it above 'z'
  399.                   ja no_drive                 ;yes, skip
  400.                   sub dl,97                   ;convert letter to byte
  401.      drv_ok:      mov ah,0Eh                  ;change drive
  402.                   int 21h                     ;call DOS
  403.                   cmp byte ptr [si+2],0       ;are we done?
  404.                   je are_done                 ;yes
  405. no_drive:         mov dx,si                   ;dx points to directory
  406.                   mov ah,3Bh                  ;set up to change
  407.                   int 21h                     ;call DOS
  408.                   jc ch_err                   ;if err don't zero AX
  409. are_done:         mov ax,0                    ;AX = 0
  410. ch_err:           mov [bp+6],ax               ;return function result
  411.                   pop si                      ;restore SI
  412.                   pop bp
  413.                   ret 2
  414. chdir             endp
  415.  
  416. ;;;;;;;;;;;;;;;
  417. ;returns most significant byte of num
  418. ;function hi(num : integer) : integer;
  419. hi                proc near
  420.                   push bp
  421.                   mov bp,sp                   ;BP points to stack
  422.                   mov ax,[bp+4]               ;AX = num
  423.                   xchg ah,al                  ;swap
  424.                   mov ah,0                    ;clear upper half
  425.                   mov [bp+6],ax               ;return function result
  426.                   pop bp
  427.                   ret 2
  428. hi                endp
  429.  
  430. ;;;;;;;;;;;;;;;;;
  431. ;returns least significant byte of num
  432. ;functio lo(num : integer) : integer;
  433. lo                proc near
  434.                   push bp
  435.                   mov bp,sp                   ;BP points to stack
  436.                   mov ax,[bp+4]               ;AX = num
  437.                   mov ah,0                    ;clear upper half
  438.                   mov [bp+6],ax               ;return function result
  439.                   pop bp
  440.                   ret 2
  441. lo                endp
  442.  
  443. ;;;;;;;;;;;;;;;;;
  444. ;shifts target to the left by quantity bits
  445. ;function shiftl(target,bits : integer) : integer;
  446. shiftl            proc near
  447.                   push bp
  448.                   mov bp,sp                    ;BP points to stack
  449.                   mov cl,byte ptr [bp+4]       ;CL = bits
  450.                   mov ax,[bp+6]                ;AX = target
  451.                   shl ax,cl                    ;shift left
  452.                   mov [bp+8],ax                ;return function result
  453.                   pop bp
  454.                   ret 4
  455. shiftl            endp
  456.  
  457. ;;;;;;;;;;;;;;;;;
  458. ;shifts target to the right by quantity bits
  459. ;function shiftr(target,bits : integer) : integer;
  460. shiftr            proc near
  461.                   push bp
  462.                   mov bp,sp                   ;BP points to stack
  463.                   mov cl,byte ptr [bp+4]      ;CL = bits
  464.                   mov ax,[bp+6]               ;AX = target
  465.                   shr ax,cl                   ;shift right
  466.                   mov [bp+8],ax               ;return function result
  467.                   pop bp
  468.                   ret 4
  469. shiftr            endp
  470.  
  471. ;;;;;;;;;;;;;;;;;;
  472. ;initializes video ram address and video type variables
  473. ;procedure init_screen;
  474. init_screen       proc near
  475.                   push bp
  476.                   jmp short past_data
  477. vid_addr dw 0B000h
  478. mono_box db 1
  479. past_data:        push ds                     ;save DS
  480.                   push bx                     ;save BX
  481.                   mov ah,0Fh                  ;set up to get mode
  482.                   int 10h                     ;call BIOS
  483.                   cmp al,7                    ;is it mono?
  484.                   je mc                       ;yes
  485.                   mov ax,0B800h               ;no, set up for CGA
  486.                   mov cl,0                    ;for mono_box
  487.                   jmp short continue          ;and continue
  488. mc:               mov ax,0B000h               ;set up for mono
  489.                   mov cl,1                    ;for mono_box
  490. continue:         mov cs:vid_addr,ax          ;save video address
  491.                   mov cs:mono_box,cl          ;save the flag
  492.                   pop bx                      ;restore BX
  493.                   pop ds                      ;restore DS
  494.                   pop bp
  495.                   ret
  496. init_screen       endp
  497.  
  498. ;;;;;;;;;;;;;;;;;;;
  499. ;waits for horiz and vertical retrace before writing to video ram
  500. cga_retrace       proc near
  501. retrace:          in al,dx                    ;get status
  502.                   test al,8                   ;check retrace
  503.                   jnz horiz                   ;ok - chech horiz
  504.                   rcr al,1                    ;check retrace
  505.                   jc retrace                  ;check again
  506. horiz:            in al,dx                    ;get status
  507.                   rcr al,1                    ;check retrace
  508.                   jnc horiz                   ;test again
  509. store_it:          ret
  510. cga_retrace       endp
  511.  
  512.  
  513. ;;;;;;;;;;;;;;;;;;
  514. ;saves the video area defined by row,col, width and depth to buff
  515. ;procedure savebox(col,row,width,depth,buff);
  516. savebox           proc near
  517.                   push bp
  518.                   mov bp,sp                   ;BP points to stack
  519.                   push ds                     ;save
  520.                   push es                     ; important
  521.                   push bx                     ;   regs
  522.                   push di                     ;    on
  523.                   push si                     ;     stack
  524.                   push ss
  525.                   pop es                      ;ES = SS
  526.                   jmp short mc2               ;jump over data and proc
  527.  
  528. s_width  dw 0
  529. s_offset dw 0
  530. mc2:              mov ax,cs:vid_addr          ;get video address
  531. continue2:        mov ds,ax                   ;put in DS
  532.                   mov di,[bp+4]               ;DI points to buffer
  533.                   mov ax,[bp+10]              ;AX = row
  534.                   dec ax                      ;normalize
  535.                   mov bx,160                  ;160 bytes per row
  536.                   mul bx                      ;times number of rows
  537.                   mov si,ax                   ;SI points to video start
  538.                   mov bx,[bp+12]              ;BX = col
  539.                   dec bx                      ;normalize
  540.                   shl bx,1                    ;times 2
  541.                   mov dx,[bp+8]               ;DX = width
  542.                   shl dx,1                    ;times 2
  543.                   mov cs:s_width,dx           ;save width
  544.                   mov cs:s_offset,160         ;save offset
  545.                   sub cs:s_offset,dx          ;subtract width
  546.                   add si,bx                   ;add to SI
  547.                   mov cx,[bp+6]               ;CX = depth
  548.                   cmp cs:vid_addr,0B000h      ;mono screen?
  549.                   mov ax,8[bp]                ;AX = width
  550.                   je mono9                    ;yes, go to mono routine
  551. again9:           push cx                     ;save CX = depth
  552.                   mov cx,[bp+8]               ;CX = width
  553.                   mov dx,03DAh                ;CGA port
  554. loop9:            cli                         ;halt interrupts
  555.                   call cga_retrace            ;wait for CGA retrace
  556. store9:           movsw                       ;store the char and attribute
  557.                   sti                         ;restore interrupts
  558.                   loop loop9                  ;do again
  559.                   pop cx                      ;restore CX = depth
  560.                   add si,cs:s_offset          ;add the offset
  561.                   loop again9                 ;and continue
  562.                   jmp y_done                  ;until done
  563. mono9:            push cx                     ;save CX = depth
  564.                   mov cx,ax                   ;CX = AX = width
  565.                   rep movsw                   ;do it
  566.                   add si,cs:s_offset          ;add the offset
  567.                   pop cx                      ;restore CX = depth
  568.                   loop mono9                  ;do again
  569. y_done:           pop si                      ;restore
  570.                   pop di                      ; regs
  571.                   pop bx                      ;  from
  572.                   pop es                      ;    the
  573.                   pop ds                      ;     stack
  574.                   pop bp
  575.                   ret 10
  576. savebox           endp
  577.  
  578. ;;;;;;;;;;;;;;;;;;;;
  579. ;restores buffer to video area defined by col, row, width, and depth
  580. ;procedure restbox(col,row,width,depth,buff : integer)
  581. restbox           proc near
  582.                   push bp
  583.                   mov bp,sp                   ;BP points to stack
  584.                   push ds                     ;save
  585.                   push es                     ; important
  586.                   push bx                     ;  regs
  587.                   push di                     ;    on
  588.                   push si                     ;     stack
  589.                   mov ax,cs:vid_addr          ;AX = video address
  590.                   mov es,ax                   ;ES = video address
  591.                   mov si,[bp+4]               ;SI points to buff
  592.                   mov ax,[bp+10]              ;AX = row
  593.                   dec ax                      ;normalize
  594.                   mov bx,160                  ;160 bytes per row
  595.                   mul bx                      ;times number of rows
  596.                   mov di,ax                   ;DI points to area
  597.                   mov bx,[bp+12]              ;BX = col
  598.                   dec bx                      ;normalize
  599.                   shl bx,1                    ;times 2
  600.                   mov dx,[bp+8]               ;DX = width
  601.                   shl dx,1                    ;times 2
  602.                   mov cs:s_width,dx           ;store width
  603.                   mov cs:s_offset,160         ;store offset
  604.                   sub cs:s_offset,dx          ;DX = offset
  605.                   add di,bx                   ;DI points to area
  606.                   mov cx,[bp+6]               ;CX = depth
  607.                   cmp cs:mono_box,1           ;mono screen?
  608.                   mov ax,[bp+8]               ;AX = video segment
  609.                   je mono6                    ;go to mono routine
  610. again6:           push cx                     ;save CX = depth
  611.                   mov cx,[bp+8]               ;CX = width
  612.                   mov dx,03DAh                ;CGA port address
  613. loop6:            cli                         ;turn off interrupts
  614.                   call cga_retrace            ;wait for retrace
  615. store6:           movsw                       ;store char and attribute
  616.                   sti                         ;interrupts enabled
  617.                   loop loop6                  ;do again
  618.                   pop cx                      ;CX = depth
  619.                   add di,cs:s_offset          ;add offset to DI
  620.                   loop again6                 ;and do another row
  621.                   jmp x_done                  ;done with CGA
  622. mono6:            push cx                     ;save CX = depth
  623.                   mov cx,ax                   ;CX = width
  624.                   rep movsw                   ;move all at once
  625.                   add di,cs:s_offset          ;add offset to DI
  626.                   pop cx                      ;CX = depth
  627.                   loop mono6                  ;do another row
  628. x_done:           pop si                      ;restore
  629.                   pop di                      ; regs
  630.                   pop bx                      ;  from
  631.                   pop es                      ;   the
  632.                   pop ds                      ;    stack
  633.                   pop bp
  634.                   ret 10
  635. restbox           endp
  636.  
  637. ;;;;;;;;;;;;;;;;;;;;;;;
  638. ;writes a string directly to video ram
  639. ; procedure screenwrite(col,row,attr:integer; var str : string);
  640. screenwrite       proc near
  641.                   push bp
  642.                   mov bp,sp                   ;BP points to stack
  643.                   push es                     ;save
  644.                   push bx                     ; regs
  645.                   push di                     ;  on
  646.                   push si                     ;   stack
  647.                   mov ax,[bp+8]               ;AX = row
  648.                   dec ax                      ;normalize
  649.                   mov bx,160                  ;160 bytes per row
  650.                   mul bx                      ;AX = AX * 160
  651.                   mov di,ax                   ;DI points to video area
  652.                   mov bx,[bp+10]              ;BX = col
  653.                   dec bx                      ;normalize
  654.                   shl bx,1                    ;adjust for attr byte
  655.                   add di,bx                   ;DI = DI + col
  656.                   mov si,[bp+4]               ;SI points to string
  657.                   mov ah,[bp+6]               ;AH = attribute
  658.                   mov dx,cs:vid_addr          ;DX = video segment
  659.                   cmp byte ptr cs:mono_box,1  ;mono screen?
  660.                   mov es,dx                   ;ES = video segment
  661.                   je sw_mono                  ;yes, go to mono routine
  662.                   mov dx,03dah                ;CGA port address
  663. sw_getnext:       lodsb                       ;AL = char
  664.                   cmp al,0                    ;end of string?
  665.                   je sw_exit                  ;yes, exit
  666.                   mov cx,ax                   ;no, save AX in CX
  667.                   cli                         ;disable interrupts
  668.                   call cga_retrace            ;wait for retrace
  669. sw_store:         mov ax,cx                   ;restore AX
  670.                   stosw                       ;store word in video ram
  671.                   sti                         ;enable interrupts
  672.                   jmp sw_getnext              ;get next character
  673. sw_mono:          lodsb                       ;AL = next char
  674.                   cmp al,0                    ;end of string?
  675.                   je sw_exit                  ;yes, exit
  676.                   stosw                       ;no, store in video ram
  677.                   jmp sw_mono                 ;get next character
  678. sw_exit:          pop si                      ;restore
  679.                   pop di                      ; regs
  680.                   pop bx                      ;  from
  681.                   pop es                      ;   stack
  682.                   pop bp
  683.                   ret 8
  684. screenwrite       endp
  685.  
  686.  
  687. ;;;;;;;;;;;;;;;;;;;;;
  688. ;moves bytes from v1addr to v2addr
  689. ;procedure move(v1addr,v2addr,bytes : integer);
  690. move             proc near
  691.                  push bp
  692.                  mov bp,sp                    ;BP points to stack
  693.                  push es                      ;save
  694.                  push di                      ; regs
  695.                  push si                      ;  on stack
  696.                  mov ax,ds                    ;AX = DS
  697.                  mov es,ax                    ;ES = AX = DS
  698.                  mov si,[bp+8]                ;SI points to v1addr
  699.                  mov di,[bp+6]                ;DI points to v2addr
  700.                  mov cx,[bp+4]                ;CX number of bytes to move
  701.                  rep movsb                    ;mass move
  702.                  pop si                       ;restore
  703.                  pop di                       ; regs
  704.                  pop es                       ;  from stack
  705.                  pop bp
  706.                  ret 6
  707. move             endp
  708.  
  709. ;;;;;;;;;;;;;;;;;;;;;
  710. ;positions cursor to col, row values
  711. ;procedure setxy(col,row : integer)
  712. setxy            proc near
  713.                  push bp
  714.                  mov bp,sp                    ;BP points to stack
  715.                  push bx                      ;preserve BX
  716.                  mov bh,0                     ;page is 0
  717.                  mov ah,2                     ;for BIOS call to move cursor
  718.                  mov dh,[bp+4]                ;DH = row
  719.                  dec dh                       ;normalize
  720.                  mov dl,[bp+6]                ;DL = col
  721.                  dec dl                       ;normalize
  722.                  int 10h                      ;BIOS will move it
  723.                  pop bx                       ;restore BX
  724.                  pop bp
  725.                  ret 4
  726. setxy            endp
  727.  
  728. ;;;;;;;;;;;;;;;;;;;;;
  729. ;fills designated string with specified character
  730. ;procedure fillstr(var target : string; num,ch : integer);
  731. fillstr          proc near
  732.                  push bp
  733.                  mov bp,sp                    ;BP points to stack
  734.                  push es                      ;save ES
  735.                  mov ax,ds                    ;AX = DS
  736.                  mov es,ax                    ;ES = AX = DS
  737.                  mov di,8[bp]                 ;DI points to target string
  738.                  mov cx,6[bp]                 ;CX = num
  739.                  cmp cx,80                    ;longer than 80 char?
  740.                  jg poof                      ;yes, depart
  741.                  mov al,byte ptr 4[bp]        ;AL = ch
  742.                  cld                          ;for forward move
  743.                  rep stosb                    ;store ch in string
  744.                  mov al,0                     ;AL = 0
  745.                  stosb                        ;for end of string byte
  746. poof:            pop es                       ;restore ES
  747.                  pop bp
  748.                  ret 6
  749. fillstr          endp
  750.  
  751. ;;;;;;;;;;;;;;;;;;;;;
  752. ;adds two long integers - return result in total
  753. ;procedure addlong(var total,n1,n2 : longint)
  754. addlong          proc near
  755.                  push bp
  756.                  mov bp,sp
  757.                  push bx                      ;save
  758.                  push di                      ; regs
  759.                  push si                      ;  on stack
  760.                  mov si,[bp+6]                ;SI points to n1 low word
  761.                  mov di,[bp+4]                ;DI points to n2 low word
  762.                  mov bx,[bp+8]                ;BX points to total low word
  763.                  mov cx,2                     ;CX = 2
  764.                  clc                          ;clear carry
  765. add_em:          mov ax,[si]                  ;AX = n1
  766.                  inc si                       ;bump SI
  767.                  inc si                       ;SI now points to n1 hi word
  768.                  adc ax,[di]                  ;add n1 to n2
  769.                  inc di                       ;bump di
  770.                  inc di                       ;DI now points to n2 hi word
  771.                  mov [bx],ax                  ;store in total lo word
  772.                  inc bx                       ;bump bx
  773.                  inc bx                       ;BX now points total hi word
  774.                  loop add_em                  ;do again for hi word
  775.                  pop si                       ;restore
  776.                  pop di                       ; regs
  777.                  pop bx                       ;  from stack
  778.                  pop bp
  779.                  ret 6
  780. addlong          endp
  781.  
  782.  
  783. ;;;;;;;;;;;;;;;;;;;;
  784. ;converts a long integer into a string;
  785. ;procedure longstr( var long : longint; var str : longstr)
  786. longstr          proc near
  787.                  push bp
  788.                  mov bp,sp                    ;BP points to stack
  789.                  push ds                      ;save
  790.                  push es                      ; regs
  791.                  push bx                      ;  on
  792.                  push si                      ;   the
  793.                  push di                      ;    stack
  794.                  jmp over_dat                 ;skip over data
  795. temp_buff db 5 dup(0)
  796. lstr db 12 dup(0)
  797. over_dat:        cld                          ;set direction to forward
  798.                  mov ax,ds                    ;AX = DS
  799.                  push ax                      ;save AX, we need DS later
  800.                  mov bx,[bp+6]                ;BX points to long low word
  801.                  mov dx,[bx+2]                ;DX points to long hi word
  802.                  mov bx,[bx]                  ;BX = long low word
  803.                  mov ax,cs                    ;AX = CS
  804.                  mov ds,ax                    ;DS = AX = CS
  805.                  mov es,ax                    ;ES = AX = CS
  806.                  lea di,temp_buff             ;DI points to buffer
  807.                  mov cx,5                     ;CX = 5 (for 10 digits)
  808.                  mov al,0                     ;AL = 0
  809. clear:           stosb                        ;store a 0
  810.                  loop clear                   ;fill buffer with zeros
  811.                  mov cx,32                    ;
  812.                  test dx,8000h                ;is low word negative?
  813.                  jz no_neg                    ;no, skip code
  814.                  not dx                       ;DX = -DX
  815.                  not bx                       ;BX = -BX
  816.                  add bx,1                     ;BX = BX + 1
  817.                  adc dx,0                     ;adjust for carry
  818. no_neg:          std                          ;set direction to back
  819. l_loop:          push cx                      ;save counter
  820.                  mov cx,5                     ;five bytes=10 digits
  821.                  lea si,temp_buff             ;SI points to buffer
  822.                  add si,4                     ;SI points to buffer end
  823.                  mov di,si                    ;DI = SI
  824.                  shl bx,1                     ;grab a bit
  825.                  rcl dx,1                     ;and then rotate
  826. adjust:          lodsb                        ;load AL with byte
  827.                  adc al,al                    ;add carry
  828.                  daa                          ;decimal adjust
  829.                  stosb                        ;store in temp_buff
  830.                  loop adjust                  ;keep going
  831.                  pop cx                       ;restore counter
  832.                  loop l_loop                  ;and do again
  833.                  cld                          ;set flag to forward
  834.                  lea di,lstr                  ;DI points to lstr
  835.                  xor dx,dx                    ;DX = 0
  836.                  lea si,temp_buff             ;SI points to buffer
  837.                  mov cx,10                    ;CX = 10 characters
  838.                  xor bx,bx                    ;BX = 0
  839. x_str:           test cx,1                    ;high or low?
  840.                  jnz y_str                    ;low
  841.                  lodsb                        ;AL = char
  842.                  mov ah,al                    ;AH = AL
  843.                  push cx                      ;save CX
  844.                  mov cl,4                     ;CL = 4
  845.                  shr al,cl                    ;shift AL right 4
  846.                  pop cx                       ;restore CX
  847.                  jmp z_str                    ;do a character
  848. y_str:           mov al,ah                    ;low part
  849.                  and al,0Fh                   ;and it
  850. z_str:           test al,0Fh                  ;is it zero?
  851.                  jnz w_str                    ;no
  852.                  or bx,bx                     ;a leading zero
  853.                  jz l_next                    ;no
  854. w_str:           inc bx                       ;BX has length
  855.                  or al,'0'                    ;AL = ASCII char
  856.                  stosb                        ;store in string
  857. l_next:          loop x_str                   ;continue
  858.                  add bx,dx                    ;add 0
  859.                  jnz l_done                   ;are we done?
  860.                  inc bx                       ;bump length
  861.                  mov al,'0'                   ;make 0
  862.                  stosb                        ;store it
  863. l_done:          cld                          ;back to forward
  864.                  mov byte ptr [di],0          ;end of string byte
  865.                  pop ax                       ;restore AX
  866.                  mov es,ax                    ;ES = DS
  867.                  lea si,lstr                  ;SI points to lstr
  868.                  mov di,[bp+4]                ;DI points to str
  869.                  mov cx,12                    ;we'll move all
  870.                  rep movsb                    ;move them
  871.                  pop di                       ;restore
  872.                  pop si                       ; regs
  873.                  pop bx                       ;  from
  874.                  pop es                       ;   the
  875.                  pop ds                       ;    stack
  876.                  pop bp
  877.                  ret 4
  878. longstr          endp
  879.  
  880.  
  881. ;;;;;;;;;;;;;;;
  882. ;hides the cursor
  883. hide_cursor       proc near
  884.                   mov ah,1                    ;cursor size function
  885.                   mov ch,20h                  ;set it to 20h
  886.                   int 10h                     ;BIOS does it
  887.                   ret
  888. hide_cursor       endp
  889.  
  890. ;;;;;;;;;;;;;;;
  891. ;saves the DOS cursor for later restoration
  892. save_cursor       proc near
  893.                   jmp get_it                  ;jump past data
  894. save_curs dw 0
  895. get_it:           mov ah,3                    ;get cursor size function
  896.                   mov bh,0                    ;page is 0
  897.                   int 10h                     ;BIOS does it
  898.                   mov cs:save_curs,cx         ;CX has size - save it
  899.                   ret
  900. save_cursor       endp
  901.  
  902. ;;;;;;;;;;;;;;;
  903. ;restores the saved DOS cursor
  904. rest_cursor       proc near
  905.                   mov cx,cs:save_curs         ;retrieve cursor size
  906.                   mov ah,1                    ;set cursor size function
  907.                   int 10h                     ;BIOS does it
  908.                   ret
  909. rest_cursor       endp
  910.  
  911.  
  912. toolcode     ends
  913.              end
  914.  
  915.